/**
 * 
 */
package it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions;

import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.GUIDStorage;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.MatchManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.Character;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.BattlePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.SimplePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.Chessboard;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.EventManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.InvalidPointSettingEvent;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.OutOfMaxCharacterEvent;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.StartingPositionEvent;

import java.awt.Point;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * @author Massimo Canonaco
 *
 */
public class StartingPointAction extends AbstractCharacterAction {

	/** */ 
	static public final float GUID = GUIDStorage.STARTING_POINT_ACTION;
	
	/** */
	private StartingPositionEvent event;
	
	/** */
	private BattlePlayer battlePerformer;
	
	/** */
	public StartingPointAction(SimplePlayer player, BattlePlayer battlePerformer, Chessboard arena)
	{
		super(player,arena);
		event = new StartingPositionEvent();
		this.battlePerformer = battlePerformer;
	}

	/* (non-Javadoc)
	 * @see it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.Action#getActionIdentifier()
	 */
	@Override
	public float getActionIdentifier() 
	{
		return GUID;
	}

	/* (non-Javadoc)
	 * @see it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.Action#execute(java.util.LinkedList)
	 */
	@Override
	//TODO: throw events
	public boolean execute(LinkedList<GenericActionInfo> infos) {
		settings(infos);
		
		if(check())
		{
			end = false;
			event.setSubject(character);
			
			boolean newAdd = true;
			// If the targetPoint is changed and the character was on another cell.
			if(park.isPawnOn(character.getRow(), character.getColumn(), character))
			{
				if(character.getRow() == targetPoint.row && character.getColumn() == targetPoint.column)
				{
					newAdd = false;
				}
				else
				{
					newAdd = true;
				}
				// Drop him from the old cell.
				park.dropPawn(character.getRow(), character.getColumn());
				event.setAdd(false);
				StartingPositionEvent newEvent = new StartingPositionEvent();
				newEvent.setPoint(character.getRow(), character.getColumn());
				character.setPosition(Character.NO_POSITION, Character.NO_POSITION);
				newEvent.setAdd(false);
				newEvent.setSubject(character);
//				System.out.println("performer "+performer.getNickname() +" "+performer);
//				newEvent.setPerformer(performer);
				EventManager.getInstance().triggerEvent(newEvent);
			}
			
			if(newAdd)
			{
			event.setAdd(true);
			// Add the character to the cell.
			park.addPawn(targetPoint.row, targetPoint.column, character);
			
//			System.out.println();
			// Set the character position.
			character.setPosition(targetPoint.row, targetPoint.column);
			
			// It's a starting position, so character didn't move.
			character.makeUnmoved();
//			System.out.println("performer "+performer.getNickname() +" "+targetPoint.row+";"+targetPoint.column);
			event.setPerformer(performer);
			System.out.println("AGGIUNTO "+character.getName()+" "+targetPoint.row+" "+targetPoint.column);
			EventManager.getInstance().triggerEvent(event);
			}
			end = true;
			return true;
		}
		return false;
	}

	/**Checks if all the required values are set.
	 * @return True, it's all set; false otherwise. */
	private boolean check() 
	{
		boolean space = battlePerformer.getCharacters().size() <= MatchManager.MAX_CHARACTERS_PER_PLAYER;
//		System.out.println("BATTLE SFHSJANFKDS "+ battlePerformer.getCharacters().size());
		if(!space)
		{
			OutOfMaxCharacterEvent oomceEvent = new OutOfMaxCharacterEvent();
			oomceEvent.setPlayer(battlePerformer);
			EventManager.getInstance().triggerEvent(oomceEvent);
		}
		
		return character != null && targetPoint != null && targetPoint.isReady() && space;
	}

	/* (non-Javadoc)
	 * @see it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.Action#reset()
	 */
	@Override
	public void reset() {
		character = null;
		targetPoint = null;
//		performer = null;
	}
	
	/** */
	private void settings(LinkedList<GenericActionInfo> informations)
	{
		GenericActionInfo tempAction = null;
		float tempGUID = -1;
		
		Iterator<GenericActionInfo>iterator = informations.iterator();
		
		while(iterator.hasNext())
		{
			tempAction = iterator.next();
			tempGUID = tempAction.getGUID();
			
			if(tempGUID == AddCharacterInfo.GUID)
			{
				iterator.remove();
				
				Character content = ((AddCharacterInfo)tempAction).getCharacter();
				
				if(content.getOwner() == performer)
				{
					character = content;
				}
				else
				{
					EventManager.getInstance().triggerEvent(new InvalidPointSettingEvent(true));
				}
			}
			else if(tempGUID == ActionCoordinateInfo.GUID)
			{
				if(character != null)
				{
					iterator.remove();
					
					targetPoint = ((ActionCoordinateInfo) tempAction).getPoint();
					// If the cell is not a spawn cell or it's not free.
					if(!park.isSpawnable(targetPoint.row, targetPoint.column) || 
							(park.getPawn(targetPoint.row, targetPoint.column) != null && park.getPawn(targetPoint.row, targetPoint.column) != character))
					{
						EventManager.getInstance().triggerEvent(new InvalidPointSettingEvent(false, targetPoint.row, targetPoint.column));
						boolean b = park.getPawn(targetPoint.row, targetPoint.column) != character;
//						System.out.println("ERRORE NEL SET DEL PUNTO INIZIALE : "+b+ "da park : "+park.getPawn(targetPoint.row, targetPoint.column)+" "+character);
						targetPoint = null; 
					}
				}
			}
		}
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "STARTING";
	}
}
